package controladoras.apresentacao.modelos;

import javax.swing.table.AbstractTableModel;
import entidades.Voo;
import entidades.Cidade;
import entidades.Aeroporto;
import telas.TelaConsultaVoo;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import controladoras.apresentacao.CntrIntVoo;

/**
 * Classe modela a tabela consulta voo.
 * @author thiagoStuckert
 */
public class ModeloTabelaConsultaVoo extends AbstractTableModel {
    /**
     * Referencia para a classe ModeloTabelaCidade.
     */
    private static ModeloTabelaConsultaVoo ref;
    /**
     * Recupera a referencia para a classe caso ela exista caso contrário
     * cria um objeto.
     * @return Objeto para a classe.
     */
    public static ModeloTabelaConsultaVoo instanciar() {
        if (ref == null) {
            ref = new ModeloTabelaConsultaVoo();
        }
        return ref;
    }

    /**
     * Nome das colunas da tabela.
     */
    private String[] columnNames = {"Número do Voo", "Data Partida",
                "Data Chegada", "Horário Partida", "Horário Chegada",
                "Aeroporto Partida", "Aeroporto Chegada", "Cidade Origem",
                "Cidade Destino", "Vagas"};
    /**
     * Linhas da tabela.
     */
    private ArrayList<Voo> rows = new ArrayList();
    /**
     * Seta as linhas da tabela.
     * @param linhas Novo valor para as linhas.
     */
    public final void setRows(final ArrayList<Voo> linhas) {
        for (int i = 0; i < rows.size(); i++) {
            delRow(i);
        }
        rows.clear();
        for (int i = 0; i < linhas.size(); i++) {
            addRow(linhas.get(i));
        }
    }
    /**
     * Recupera a quantidade de colunas da tabela.
     * @return Quantidade de colunas da tabela.
     */
    @Override
    public final int getColumnCount() {
        return columnNames.length;
    }
    /**
     * Recupera a quantidade de linhas da tabela.
     * @return Quantidade de linhas da tabela.
     */
    @Override
    public final int getRowCount() {
        return rows.size();
    }
    /**
     * Recupera o nome da coluna col.
     * @param col indice da coluna.
     * @return Nome da coluna.
     */
    @Override
    public final String getColumnName(final int col) {
        return columnNames[col];
    }
    /**
     *  Recupera o valor da linha rowIndes e coluna columnIndex.
     * @param rowIndex Indice da linha.
     * @param columnIndex Indice da coluna.
     * @return objeto da da tabela[rowIndex][columnIndex].
     */
    @Override
    public final Object getValueAt(final int rowIndex, final int columnIndex) {
        Voo voo = rows.get(rowIndex);
        switch (columnIndex) {
            case 0: return voo.getNumeroVoo();
            case 1: return voo.getDataPartida();
            case 2: return voo.getDataChegada();
            case 3: return voo.getHorarioPartida();
            case 4: return voo.getHorarioChegada();
            case 5: return voo.getAeroportoPartida().getCodigoAeroporto();
            case 6: return voo.getAeroportoChegada().getCodigoAeroporto();
            case 7: return voo.getCidadeOrigem().getNomeCidade();
            case 8: return voo.getCidadeDestino().getNomeCidade();
            case 9: return Integer.toString(Integer.valueOf(voo.getVagas()));
            default: return "";
        }
    }

     /**
      * Determina quais celulas serão editáveis.
      * @param row linha da tabela.
      * @param col coluna da tabela.
      * @return boolean true se for editável ou false caso contrário.
      */
    @Override
     public final boolean isCellEditable(final int row, final int col) {
        return false;
     }

     /**
      * Adiciona um voo na tabela.
      * @param voo Objeto a ser adicionado na tabela.
      */
     public final void addRow(final Voo voo) {
         rows.add(voo);
         int linha = rows.size() - 1;
         fireTableRowsInserted(linha, linha);
         return;
     }
    /**
     * Deleta uma linha da tabela.
     * @param row linha a ser deletada da tabela.
     */
    public final void delRow(final int row) {
        rows.remove(row);
        fireTableRowsDeleted(row, row);
    }
    /**
     * Seta o valor da tabela[row][col].
     * @param value valor novo da célula.
     * @param row linha da tabela.
     * @param col coluna da tabela.
     */
    @Override
    public final void setValueAt(final Object value, final int row,
            final int col) {
        String entrada = (String) value;
        Voo vooNovo = rows.get(row);
        Voo vooVelho = new Voo(vooNovo.getNumeroVoo(),
                               vooNovo.getDataPartida(),
                               vooNovo.getDataChegada(),
                               vooNovo.getHorarioPartida(),
                               vooNovo.getHorarioChegada(),
                               vooNovo.getAeroportoPartida(),
                               vooNovo.getAeroportoChegada(),
                               vooNovo.getCidadeOrigem(),
                               vooNovo.getCidadeDestino(),
                               vooNovo.getVagas());
         try {
            switch (col) {
                case 0:
                    vooNovo.setNumeroVoo(entrada);
                    break;
                case 1:
                    vooNovo.setDataPartida(entrada);
                    break;
                case 2:
                    vooNovo.setDataChegada(entrada);
                    break;
                case 3:
                    vooNovo.setHorarioPartida(entrada);
                    break;
                case 4:
                    vooNovo.setHorarioChegada(entrada);
                    break;
                case 5:
                    vooNovo.setAeroportoPartida(new Aeroporto(entrada));
                    break;
                case 6:
                    vooNovo.setAeroportoChegada(new Aeroporto(entrada));
                    break;
                case 7:
                    vooNovo.setCidadeOrigem(new Cidade((entrada)));
                    break;
                case 8:
                    vooNovo.setCidadeDestino(new Cidade((entrada)));
                    break;
                case 9:
                    vooNovo.setVagas(Integer.parseInt(entrada));
                    break;
                default: break;
            }
            CntrIntVoo cntrIntVoo = CntrIntVoo.instanciar();
            cntrIntVoo.upVoo(vooVelho, vooNovo);

         } catch (Exception e) {
             TelaConsultaVoo telaConsultaVoo = TelaConsultaVoo.instanciar();
             JOptionPane.showMessageDialog(telaConsultaVoo,
                     e.getMessage());
             /*Recupero a linha anterior*/
             rows.set(row, vooVelho);
         }
         fireTableCellUpdated(row, col);
     }
}
